using B.S.XZYData.Api.Wrter.Application.Command.WorkReport;
using DomainWorkReport = B.S.XZYData.Domain.ZSH.WorkReport;
using DomainWorkReportDefectiveItem = B.S.XZYData.Domain.ZSH.WorkReportDefectiveItem;
using B.S.XZYData.Domain.ZSH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;

namespace B.S.XZYData.Api.Wrter.Application.Handler.WorkReport
{
    /// <summary>
    /// 编辑报工处理器
    /// </summary>
    public class EditWorkReportHandler : IRequestHandler<EditWorkReportCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<DomainWorkReport> _workReportRepo;
        private readonly IBaseRepository<DomainWorkReportDefectiveItem> _defectiveItemRepo;

        public EditWorkReportHandler(IBaseRepository<DomainWorkReport> workReportRepo,
                                      IBaseRepository<DomainWorkReportDefectiveItem> defectiveItemRepo)
        {
            _workReportRepo = workReportRepo;
            _defectiveItemRepo = defectiveItemRepo;
        }

        public async Task<ApiResult<int>> Handle(EditWorkReportCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<int>();

            if (request.Id <= 0)
            {
                res.Code = ApiEnum.Fail;
                res.Msg = "报工 Id 无效";
                return await Task.FromResult(res);
            }

            // 基本校验
            if (string.IsNullOrWhiteSpace(request.WorkOrderCode))
            {
                res.Code = ApiEnum.Fail;
                res.Msg = "工单编号不能为空";
                return await Task.FromResult(res);
            }
            if (request.ReportQty <= 0)
            {
                res.Code = ApiEnum.Fail;
                res.Msg = "报工数量必须大于0";
                return await Task.FromResult(res);
            }
            
            // 添加更多验证
            if (string.IsNullOrWhiteSpace(request.ProcessName))
            {
                res.Code = ApiEnum.Fail;
                res.Msg = "工序名称不能为空";
                return await Task.FromResult(res);
            }
            if (string.IsNullOrWhiteSpace(request.Producer))
            {
                res.Code = ApiEnum.Fail;
                res.Msg = "生产人员不能为空";
                return await Task.FromResult(res);
            }
            
            // 验证枚举值
            if (!Enum.IsDefined(typeof(ProcessStatusEnum), request.ProcessStatus))
            {
                res.Code = ApiEnum.Fail;
                res.Msg = $"工序状态值无效: {request.ProcessStatus}";
                return await Task.FromResult(res);
            }
            if (!Enum.IsDefined(typeof(PricingMethodEnum), request.PricingMethod))
            {
                res.Code = ApiEnum.Fail;
                res.Msg = $"计价方式值无效: {request.PricingMethod}";
                return await Task.FromResult(res);
            }

            try
            {
                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);

                // 获取现有报工记录
                var workReport = await _workReportRepo.GetValue(request.Id);
                if (workReport == null || workReport.IsDeleted)
                {
                    res.Code = ApiEnum.Fail;
                    res.Msg = "未找到报工记录或已被删除";
                    return res;
                }

                // 更新主表字段
                workReport.WorkOrderCode = request.WorkOrderCode;
                workReport.ProcessName = request.ProcessName;
                workReport.ProductCode = request.ProductCode;
                workReport.ProductNo = request.ProductNo;
                workReport.ProductName = request.ProductName;
                workReport.ProductSpec = request.ProductSpec;
                workReport.ReportQty = request.ReportQty;
                workReport.Producer = request.Producer;
                workReport.Unit = request.Unit;
                workReport.GoodQty = request.GoodQty;
                workReport.DefectiveQty = request.DefectiveQty;
                workReport.ProcessStatus = request.ProcessStatus;
                workReport.ProcessProgress = request.ProcessProgress;
                workReport.StartTime = request.StartTime;
                workReport.EndTime = request.EndTime;
                workReport.ReportHours = request.ReportHours;
                workReport.ReportMinutes = request.ReportMinutes;
                workReport.PricingMethod = request.PricingMethod;
                workReport.WageUnitPrice = request.WageUnitPrice;
                workReport.EstimatedWage = request.EstimatedWage;
                workReport.BonusAmount = request.BonusAmount;
                workReport.PenaltyAmount = request.PenaltyAmount;
                workReport.ModifyTime = DateTime.Now;
                workReport.ModifierId = request.ModifierId;

                // 自动计算效率相关字段
                CalculateEfficiencyFields(workReport);

                var updateResult = await _workReportRepo.UpdateAsync(workReport);
                if (updateResult <= 0)
                {
                    res.Code = ApiEnum.Fail;
                    res.Msg = "更新报工失败";
                    return res;
                }

                // 处理不良品项
                int defectiveRows = 0;
                // 先伪删除旧的不良品项
                var oldDefectiveItems = _defectiveItemRepo.GetAll()
                    .Where(x => x.WorkReportId == request.Id && !x.IsDeleted)
                    .ToList();
                if (oldDefectiveItems.Count > 0)
                {
                    foreach (var item in oldDefectiveItems)
                    {
                        item.IsDeleted = true;
                        item.ModifyTime = DateTime.Now;
                        item.ModifierId = request.ModifierId;
                    }
                    await _defectiveItemRepo.UpdateBatchAsync(oldDefectiveItems);
                }

                // 插入新的不良品项
                if (request.DefectiveItems != null && request.DefectiveItems.Any())
                {
                    var newDefectiveEntities = request.DefectiveItems.Select(d => new DomainWorkReportDefectiveItem
                    {
                        WorkReportId = request.Id,
                        DefectiveCode = d.DefectiveCode,
                        DefectiveQty = d.DefectiveQty,
                        CreateTime = DateTime.Now,
                        CreatorId = request.ModifierId,
                        IsDeleted = false
                    }).ToList();

                    defectiveRows = await _defectiveItemRepo.CreateBatchAsync(newDefectiveEntities);
                }

                scope.Complete();

                res.Code = ApiEnum.Success;
                res.Msg = "更新报工成功";
                res.Data = updateResult + defectiveRows;
                return res;
            }
            catch (Exception ex)
            {
                res.Code = ApiEnum.Error;
                res.Msg = $"更新报工异常：{ex.Message}";
                
                // 记录详细的异常信息用于调试
                Console.WriteLine($"更新报工异常详情: {ex}");
                if (ex.InnerException != null)
                {
                    Console.WriteLine($"内部异常: {ex.InnerException.Message}");
                    res.Msg += $" 内部异常：{ex.InnerException.Message}";
                }
                
                return res;
            }
        }

        /// <summary>
        /// 自动计算效率相关字段
        /// </summary>
        /// <param name="workReport">报工记录</param>
        private void CalculateEfficiencyFields(DomainWorkReport workReport)
        {
            // 计算总工时（小时）
            decimal totalHours = workReport.ReportHours + (decimal)workReport.ReportMinutes / 60;
            
            if (totalHours > 0 && workReport.ReportQty > 0)
            {
                // 实际效率 = 产量 / 工时（件/小时）
                workReport.ActualEfficiency = Math.Round(workReport.ReportQty / totalHours, 2);
                
                // 标准效率暂时设为固定值，实际项目中应从工序标准工时表获取
                // 这里假设标准效率为每小时10件
                workReport.StandardEfficiency = 10;
                
                // 达标率 = (实际效率 / 标准效率) × 100%
                if (workReport.StandardEfficiency > 0)
                {
                    workReport.ComplianceRate = Math.Round((workReport.ActualEfficiency / workReport.StandardEfficiency) * 100, 2);
                }
                else
                {
                    workReport.ComplianceRate = 0;
                }
            }
            else
            {
                // 如果工时或产量为0，则效率为0
                workReport.StandardEfficiency = 10; // 保持标准值
                workReport.ActualEfficiency = 0;
                workReport.ComplianceRate = 0;
            }
        }
    }
} 